iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
AI & Data

從0開始的MLFLOW應用搭建系列 第 17

Day 17 – 本地 Serve 模型為 API(註冊 + Staging 版)

  • 分享至 

  • xImage
  •  

背景與目標

到目前為止,我們已經能在 MLflow 裡追蹤模型實驗結果。
但如果要提供服務,僅用 run_id 方式不穩定(容易消失,無版本控制)。

👉 今天我們要:

  1. 重新訓練一個 Popular Top-10 模型
  2. 註冊到 Model Registry(名稱:AnimeRecsysModel)。
  3. 把它的版本設為 Staging
  4. mlflow models serve 在本地啟動成 REST API。
  5. curl 測試推薦結果。

Notebook 準備

請建立 notebooks/day17_serve_with_registry.ipynb,貼上下列程式。


1. 載入資料並訓練模型

import os
import pandas as pd
import mlflow
import mlflow.pyfunc
from mlflow.tracking import MlflowClient

# 設定 MLflow Tracking
mlflow.set_tracking_uri("http://mlflow:5000")
mlflow.set_experiment("anime-recsys-serve")

# 資料路徑
DATA_DIR = "/usr/mlflow/data"
anime = pd.read_csv(os.path.join(DATA_DIR, "anime_clean.csv"))
ratings_train = pd.read_csv(os.path.join(DATA_DIR, "ratings_train.csv"))

print("Anime:", anime.shape)
print("Train:", ratings_train.shape)

# 訓練 Popular Top-10 模型
top10 = (
    ratings_train.groupby("anime_id")["rating"]
    .mean()
    .reset_index()
    .merge(anime[["anime_id", "name"]], on="anime_id")
    .sort_values("rating", ascending=False)
    .head(10)
)

top10_ids = top10["anime_id"].tolist()
top10_names = top10["name"].tolist()
print("Top 10 Anime:", top10_names)

# 定義 PopularTop10 模型
class PopularTop10(mlflow.pyfunc.PythonModel):
    def __init__(self, anime_df, top10_ids):
        self.anime = anime_df
        self.top10_ids = top10_ids

    def predict(self, context, model_input):
        # 輸入是動畫名稱,但 PopularTop10 不看輸入,永遠回傳 Top10
        return [self.anime[self.anime["anime_id"].isin(self.top10_ids)]["name"].tolist()]

2. 註冊模型到 Registry

client = MlflowClient()

with mlflow.start_run(run_name="popular-top10-registry") as run:
    mlflow.log_param("model_type", "PopularTop10")

    # 註冊模型到 Registry
    result = mlflow.pyfunc.log_model(
        artifact_path="model",
        python_model=PopularTop10(anime, top10_ids),
        registered_model_name="AnimeRecsysModel"
    )

    run_id = run.info.run_id
    print("Run ID:", run_id)

# 找到剛剛註冊的最新版本
latest_versions = client.get_latest_versions("AnimeRecsysModel")
for v in latest_versions:
    print("Version:", v.version, "Stage:", v.current_stage)
    new_version = v.version  # 取最新的 version

3. 把模型設為 Staging

# 把最新版本移到 Staging
client.transition_model_version_stage(
    name="AnimeRecsysModel",
    version=new_version,
    stage="Staging",
    archive_existing_versions=True
)

print(f"✅ Model AnimeRecsysModel v{new_version} 已移到 Staging")

現在到 MLflow UI → Models → AnimeRecsysModel → 你會看到這個版本是 Staging
https://ithelp.ithome.com.tw/upload/images/20250925/2017862636HASprWDn.png

https://ithelp.ithome.com.tw/upload/images/20250925/20178626OumKAJn6T8.png


4. Serve 成 API

在容器裡執行(注意 Stage):

mlflow models serve -m "models:/AnimeRecsysModel/Staging" -p 5001 --no-conda

這會啟動一個 REST API 在 **http://127.0.0.1:5001**。
https://ithelp.ithome.com.tw/upload/images/20250925/20178626blYNqjov5Y.png


5. 測試 API

開新 terminal,送一個請求:

curl -X POST http://127.0.0.1:5001/invocations \
  -H "Content-Type: application/json" \
  -d '{
        "inputs": [["Naruto"]]
      }'

輸出結果會是 Top-10 的動畫清單:

https://ithelp.ithome.com.tw/upload/images/20250925/20178626XQWcGJxDjy.png


流程圖

訓練 PopularTop10
       │
       ▼
 mlflow.pyfunc.log_model (registered_model_name="AnimeRecsysModel")
       │
       ▼
 MLflow Registry
   ├── v1 → Staging
   └── (之後可有 v2, v3…)
       │
       ▼
 mlflow models serve (Staging)
       │
       ▼
 REST API → POST /invocations

重點總結

  • 今天我們完成了 訓練 → 註冊模型 → 設定 Stage → Serve 成 API

  • 和 run_id 相比,Model Registry 的好處是:

    • 有版本號(v1, v2, …)。
    • 有 Stage(Staging, Production, Archived)。
    • 可以穩定 serve,避免 run artifacts 遺失。
  • 企業級推薦系統應該用 Registry + Stage,而不是 run_id。

👉 下一步(Day 18),我們會做一個 模型追蹤與部署總結,整理整個 MLflow 部署管線。


上一篇
Day 16 – 模型解釋與 Logging(單一樣本 + 全資料集平均權重)
下一篇
Day 18 – 模型追蹤與部署總結
系列文
從0開始的MLFLOW應用搭建23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言